added fish time usage profiling
authorØyvind Kolås <ok@src.gnome.org>
Tue, 27 Sep 2005 18:23:57 +0000 (18:23 +0000)
committerØyvind Kolås <ok@src.gnome.org>
Tue, 27 Sep 2005 18:23:57 +0000 (18:23 +0000)
ChangeLog
babl/babl-classes.h
babl/babl-fish-path.c
babl/babl-fish-stats.c
babl/babl-internal.c
babl/babl-introspect.c
babl/babl-util.c
extensions/gggl.c

index b5b76b36f6fc970845cd34ce7d8117649ea6de1d..ffc0285afb70731062f2416dc89eea09de9bafbc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-09-27  Øyvind Kolås  <pippin@gimp.org>
+
+       * babl/babl-classes.h: Added time consumption instrumentation to
+       BablFish.
+       * babl/babl-fish-path.c: (babl_fish_path), (babl_fish_path_process):
+       intialization of instrumentation data.
+       * babl/babl-fish-stats.c: (table_destination_each), (each_conv),
+       (conversions), (babl_fish_stats): Output timing data, as well as a
+       list of all conversions with the obviously bad ones marked in red.
+       * babl/babl-internal.c: (babl_process): update instrumentation.
+       * babl/babl-introspect.c: (conversion_introspect): only query error
+       from conversions where that is legal.
+       * babl/babl-util.c: changed from msecs to nsecs (might be some more
+       places in the code to change names of variables.)
+       * extensions/gggl.c: (conv_gF_gaF), (conv_gF_rgbF), (conv_rgbF_gF),
+       (conv_rgbaF_rgb8): Changes to increase sanity.
+
 2005-09-27  Øyvind Kolås  <pippin@gimp.org>
 
        * tests/srgb_to_lab_u8.c: (test): renamed format (srgb -> R'G'B' u8)
index e7ab444426d5e11af5c7460bfe9532a9044cc607..63ed19e15492d5b612cf65ac7934f2ec16ae92b1 100644 (file)
@@ -189,21 +189,20 @@ typedef struct
   int            *stride;
 } BablImage;
 
-/* BablFish base class, the user of babl is just requesting a
- * conversion, after that an appropriate species of fish is
- * constructed to handle the request.
- * 
- * TODO:
- *   * implement 
+/* BablFish, common base class for various fishes.
  */
 typedef struct
 {
   BablInstance    instance;
   union Babl     *source;
   union Babl     *destination;
-  int             processings;
-  long            pixels;
-  double          error;
+
+  double          error;    /* the amount of noise introduced by the fish */
+
+  /* instrumentation */
+  int             processings; /* number of times the fish has been used */
+  long            pixels;      /* number of pixels translates */
+  long            msecs;       /* msecs spent within this fish */
 } BablFish;
 
 
@@ -211,6 +210,8 @@ typedef struct
 /* BablFishSimple is the simplest type of fish, wrapping a single
  * conversion function, (note this might not be the optimal chosen
  * conversion even if it exists)
+ *
+ * TODO: exterminate
  */
 typedef struct
 {
@@ -221,39 +222,35 @@ typedef struct
 
 
 /* BablFishPath is a combination of registered conversions, both
- * from the reference types / model conversions, and optimized paths.
+ * from the reference types / model conversions, and optimized format to
+ * format conversion.
  *
  * This is the most advanced scheduled species of fish, some future
- * version of babl might even be evovling combined fishes in a background
- * thread, based on profiled usage. For this to work in a future version
- * transmogrification between the fish classes would be used.
+ * version of babl might even be evovling path fishes in a background
+ * thread, based on the fish instrumentation. For this to work in a future
+ * version transmogrification between the fish classes would be used.
  */
 typedef struct
 {
   BablFish         fish;
-  double           cost;
-  double           loss;
+  double           cost;   /* number of  ticks *10 + chain_length */
+  double           loss;   /* error introduced */
+
   BablConversion  *conversion[BABL_HARD_MAX_PATH_LENGTH];
   int              conversions;
 } BablFishPath;
 
-/* BablFishReference on the double versions of conversions
- * that are required to exist for maximum sanity.
+/* BablFishReference 
  *
  * A BablFishReference is not intended to be fast, thus the algorithm
- * encoded can use a multi stage approach, where some of the stages could
- * be completely removed for optimization reasons.
- *
- * This is not the intention of the "BablFishReference factory", it's
- * implementation is meant to be kept as small as possible wrt logic.
+ * encoded can use a multi stage approach, based on the knowledge babl
+ * has encoded in the pixel formats.
  *
  * One of the contributions that would be welcome are new fish factories.
  *
  * TODO:
- *   * cache the looked up conversions, removing all overhead but the
- *     actual conversions.
  *   * make optimal use of a single allocation containing enough space
- *     for the maximum amount of memory needed in to adjecant buffers
+ *     for the maximum amount of memory needed in two adjecant buffers
  *     at any time.
  */
 typedef struct
@@ -263,7 +260,7 @@ typedef struct
 
 typedef struct
 {
-  BablInstance   instance;               /* path to .so / .dll is stored in instance name */
+  BablInstance   instance; /* path to .so / .dll is stored in instance name */
   void          *dl_handle;
   void         (*destroy) (void); 
 } BablExtension;
index 23b29765122ec7d04676d6522992f22d9087b612..092ca6c02c860110d46f236f446a8455510d28ec 100644 (file)
@@ -292,6 +292,7 @@ babl_fish_path (Babl   *source,
 
   babl->fish.processings = 0;
   babl->fish.pixels      = 0;
+  babl->fish.msecs       = 0;
   babl->fish.error       = 200000;
 
   babl->fish_path.cost        = 200000;
@@ -399,14 +400,18 @@ babl_fish_path_process (Babl *babl,
                         void *destination,
                         long n)
 {
+  long ret;
+
   babl_assert (source);
   babl_assert (destination);
-  
-  return chain_process (babl->fish_path.conversion,
-                        babl->fish_path.conversions,
-                        source,
-                        destination,
-                        n);
+
+  ret = chain_process (babl->fish_path.conversion,
+                       babl->fish_path.conversions,
+                       source,
+                       destination,
+                       n);
+
+  return ret;
 }
 
 
index b34b03c3643f2beb84a0d57a7045938a8d6fc53a..e02e6d3770eafce5a85f0c881e8ea7d9f9dd47f6 100644 (file)
@@ -57,6 +57,7 @@ table_destination_each (Babl *babl,
               fprintf (output_file, "<h3><span class='g'>path</span> %s <span class='g'>to</span> %s</h3>", source->instance.name, destination->instance.name);
               if (fish->fish.processings > 0)
                 {
+                  fprintf (output_file, "<span class='g'>msecs:</span>%li<br/>", fish->fish.msecs);
                   fprintf (output_file, "<span class='g'>Processings:</span>%i<br/>", fish->fish.processings);
                   fprintf (output_file, "<span class='g'>Pixels:</span>%li<br/>", fish->fish.pixels);
                 }
@@ -95,6 +96,7 @@ table_destination_each (Babl *babl,
 
               if (fish->fish.processings > 0)
                 {
+                  fprintf (output_file, "<span class='g'>msecs:</span>%li<br/>", fish->fish.msecs);
                   fprintf (output_file, "<span class='g'>Processings:</span>%i<br/>", fish->fish.processings);
                   fprintf (output_file, "<span class='g'>Pixels:</span>%li<br/>", fish->fish.pixels);
                 }
@@ -175,6 +177,42 @@ table_source_each (Babl *babl,
   return 0;
 }
 
+static int
+each_conv (Babl *babl,
+           void *data)
+{
+  double error, cost;
+
+  if (BABL(babl->conversion.source)->class_type != BABL_FORMAT)
+    return 0;
+
+  error = babl_conversion_error (&babl->conversion);
+  cost  = babl_conversion_cost  (&babl->conversion);
+
+  if (error>0.01)
+    {
+      fprintf (output_file, "<dt style='background-color: #fcc;'>%s</dt>", babl->instance.name);
+      fprintf (output_file, "<dd style='background-color: #fcc;'>");
+    }
+  else
+    {
+      fprintf (output_file, "<dt>%s</dt><dd>", babl->instance.name);
+    }
+  fprintf (output_file, "<em>error:</em> %f <em>cost:</em> %4.0f <em>processings:</em> %i <em>pixels:</em> %li", error, cost,
+            babl->conversion.processings, babl->conversion.pixels);
+  fprintf (output_file, "</dd>");
+   
+  return 0;
+}
+
+static void
+conversions ()
+{
+  fprintf (output_file, "<h2>Conversions</h2><dl>\n");
+  babl_conversion_each (each_conv, NULL);
+  fprintf (output_file, "</dl>\n");
+}
+
 void
 babl_fish_stats (FILE *file)
 {
@@ -303,6 +341,8 @@ babl_fish_stats (FILE *file)
 
   fprintf (output_file, "<div style='height:20em'></div>\n");
 
+  conversions ();
+
   fprintf (output_file, "</body></html>\n");
 }
 
index ae7bc265b9955e3151a902a5057f95945bf02abc..73af0127f65689f34283618df5dabbe8419d6867 100644 (file)
@@ -97,9 +97,17 @@ babl_process (Babl *babl,
       babl->class_type == BABL_FISH_PATH ||
       babl->class_type == BABL_FISH_SIMPLE)
     {
+       long ret;
+       long ticks = babl_ticks ();
+       ret = babl_fish_process (babl, source, destination, n);
+
+       ticks -= babl_ticks();
+       ticks *= -1;
+
+       babl->fish.msecs += ticks;
        babl->fish.processings++;
-       babl->fish.pixels += n;
-       return babl_fish_process (babl, source, destination, n);
+       babl->fish.pixels += ret;
+       return ret;
     }
 
   babl_fatal ("eek");
index e61b47406ab3a3e65f5dcff7e07a170c0e17ae3e..67379dec272cd4ba191f41c3c353e3ee65fa30d6 100644 (file)
@@ -165,9 +165,10 @@ conversion_introspect (Babl *babl)
 {
   babl_log ("\t\tprocessings:%i pixels:%li",
             babl->conversion.processings, babl->conversion.pixels);
-  babl_log ("\t\tcost: %i   error: %f",
-     babl_conversion_cost (&babl->conversion),
-     babl_conversion_error (&babl->conversion));
+  if (BABL(babl->conversion.source)->class_type == BABL_FORMAT)
+    {
+      babl_log ("\t\terror: %f", babl_conversion_error (&babl->conversion));
+    }
 }
 
 static void
index 63284fb8251dab5f5a2676f94184a5c725d2f52c..032ee600f6ff5db58fb7669af50133597a7980f1 100644 (file)
@@ -82,7 +82,7 @@ babl_list_each (void             **list,
 static struct timeval start_time;
 static struct timeval measure_time;
 
-#define msecs(time) ((time.tv_sec-start_time.tv_sec)*1000 + time.tv_usec/1000)
+#define msecs(time) ((time.tv_sec-start_time.tv_sec)*10000000 + time.tv_usec)
 
 static void
 init_ticks (void)
index b5dc30d929d5c9a69962a86ffe3bdad0f5fbeef9..e26ab72f811f53facb94577b9962e0c776042e1a 100644 (file)
@@ -687,7 +687,7 @@ conv_gF_gaF (unsigned char *src, unsigned char *dst, long samples)
   long n=samples;
   while (n--)
     {
-      *(int *) dst = (*(int *) src);
+      *(float *) dst = (*(float *) src);
       dst += 4;
       src += 4;
       *(float *) dst = 1.0;
@@ -714,7 +714,7 @@ conv_gF_rgbF (unsigned char *src, unsigned char *dst, long samples)
 
       for (c = 0; c < 3; c++)
         {
-          (*(int *) dst) = (*(int *) src);
+          (*(float *) dst) = (*(float *) src);
           dst += 4;
         }
       src += 4;
@@ -736,7 +736,7 @@ conv_rgbF_gF (unsigned char *src, unsigned char *dst, long samples)
           sum += (*(float *) src);
           src += 4;
         }
-      sum /= 3;
+      sum /= 3.0;
       (*(float *) dst) = sum;
       dst += 4;
     }
@@ -869,7 +869,13 @@ conv_rgbaF_rgb8 (unsigned char *src, unsigned char *dst, long samples)
 
       for (c = 0; c < 3; c++)
         {
-          *(unsigned char *) dst = rint ((*(float *) src) * 255.0);
+          int val=rint ((*(float *) src) * 255.0);
+          if (val<0)
+            *(unsigned char *) dst = 0;
+          else if (val>255)
+            *(unsigned char *) dst = 255;
+          else
+            *(unsigned char *) dst = val;
           dst += 1;
           src += 4;
         }